package com.zzyl.nursing.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zzyl.nursing.domain.Device;
import com.zzyl.nursing.domain.DeviceData;
import com.zzyl.nursing.domain.amqp.IotMsgBody;
import com.zzyl.nursing.domain.amqp.IotMsgHeader;
import com.zzyl.nursing.domain.amqp.IotMsgNotifyData;
import com.zzyl.nursing.domain.amqp.IotMsgService;
import com.zzyl.nursing.dto.DeviceDataPageDto;
import com.zzyl.nursing.mapper.DeviceMapper;
import com.zzyl.nursing.mapper.IDeviceDataMapper;
import com.zzyl.nursing.service.IDeviceDataService;
import com.zzyl.nursing.vo.DeviceDataPageVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class IDeviceDataServiceImpl implements IDeviceDataService {

    @Autowired
    private IDeviceDataMapper deviceDataMapper;

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    String IOT_DEVICE_LAST_DATA = "IOT_DEVICE_LAST_DATA:";

    @Override
    public void insertDevice(IotMsgNotifyData data) {
        log.info("调用insertDevice方法，开始解析传参数据入库");
        List<DeviceData> deviceDataList = new ArrayList<>();

        IotMsgHeader header = data.getHeader();
        IotMsgBody body = data.getBody();

        //先用设备id拿到基础数据
        LambdaQueryWrapper<Device> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Device::getIotId, header.getDeviceId());
        Device device = deviceMapper.selectOne(wrapper);
        log.info("设备基础数据为：{}", device);

        List<IotMsgService> services = body.getServices();
        for (IotMsgService service : services) {
            log.info("服务数据为：{}", service);
            Map<String, Object> properties = service.getProperties();
            String eventTimeString = service.getEventTime();
            Date eventTime = DateUtil.parse(eventTimeString, "yyyyMMdd'T'HHmmss'Z'");
            log.info("拿到properties为：{}", properties);
            properties.forEach((key, value) -> {
                DeviceData deviceData = new DeviceData();
                BeanUtil.copyProperties(device, deviceData);
                deviceData.setFunctionId(key);
                deviceData.setDataValue(value.toString());
                deviceData.setAlarmTime(eventTime);
                deviceDataList.add(deviceData);
            });
        }
        log.info("开始往数据库插入列表");
        try {
            deviceDataMapper.insertList(deviceDataList);
            redisTemplate.opsForValue().set(IOT_DEVICE_LAST_DATA + device.getIotId(), JSONUtil.toJsonStr(deviceDataList));
        } catch (Exception e) {
            log.info("插入数据异常：{}", e.getMessage());
        }
    }

    @Override
    public DeviceDataPageVo page(DeviceDataPageDto dto) {
        Date startTime = dto.getStartTime();
        Date endTime = dto.getEndTime();
        String deviceName = dto.getDeviceName();
        String functionId = dto.getFunctionId();
        Integer pageNum = dto.getPageNum();
        Integer pageSize = dto.getPageSize();

        Page<DeviceData> deviceDataPage = new Page<>(pageNum, pageSize);

        LambdaQueryWrapper<DeviceData> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(functionId != null, DeviceData::getFunctionId, functionId)
                .eq(deviceName != null, DeviceData::getDeviceName, deviceName)
                .ge(startTime != null, DeviceData::getAlarmTime, startTime)
                .le(endTime != null, DeviceData::getAlarmTime, endTime);

        Page<DeviceData> dataPage = deviceDataMapper.selectPage(deviceDataPage, wrapper);

        DeviceDataPageVo deviceDataPageVo = new DeviceDataPageVo();
        deviceDataPageVo.setTotal(dataPage.getTotal());
        deviceDataPageVo.setRecords(dataPage.getRecords());
        deviceDataPageVo.setPages(dataPage.getPages());
        deviceDataPageVo.setPage(dataPage.getCurrent());
        deviceDataPageVo.setPageSize(dataPage.getSize());
        return deviceDataPageVo;
    }
}
